//////////////////////////////////////////////////////////////////////////////
//
//  Created by Philip Mulcahy on 23/02/2013.
//  Copyright (c) 2013 Philip Mulcahy. All rights reserved.
//
//  This file is part of the note-recog library.
//
//  note-recog is free software: you can redistribute it and/or modify
//  it under the terms of version 3 of the GNU Lesser General Public License 
//  as published by the Free Software Foundation.
//
//  note-recog is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with note-recog. If not, see <http://www.gnu.org/licenses/>.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef note_recog_SequenceTransformer_h
#define note_recog_SequenceTransformer_h


#include "IIterable.h"


template<typename IN, typename OUT, typename FUNCTOR>
class SequenceTransformer : public IIterable<OUT>
{
private:
    IIterable<IN>& _source;
    FUNCTOR& _func;
    
public:
    SequenceTransformer(IIterable<IN>& source, FUNCTOR& func);
    virtual ~SequenceTransformer();
    virtual OUT next();
    virtual bool hasNext() const;
};

//////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION
//////////////////////////////////////////////////////////////////////////////


template<typename IN, typename OUT, typename FUNCTOR>
SequenceTransformer<IN,OUT,FUNCTOR>::SequenceTransformer(IIterable<IN>& source, FUNCTOR& func)
: _source(source),
  _func(func)
{}


template<typename IN, typename OUT, typename FUNCTOR>
SequenceTransformer<IN,OUT,FUNCTOR>::~SequenceTransformer()
{}


template<typename IN, typename OUT, typename FUNCTOR>
OUT SequenceTransformer<IN,OUT,FUNCTOR>::next()
{
    IN i = _source.next();
    OUT o = _func(i);
    return o;
}


template<typename IN, typename OUT, typename FUNCTOR>
bool SequenceTransformer<IN,OUT,FUNCTOR>::hasNext() const
{
    return _source.hasNext();
}


#endif
